home *** CD-ROM | disk | FTP | other *** search
/ Creative Computers / Creative Computers CD-ROM, Volume 1 (Legendary Design Technologies, Inc.)(1994).iso / shareware / fractals / cpm / cpm.c < prev    next >
C/C++ Source or Header  |  1994-11-17  |  8KB  |  319 lines

  1. #include <exec/types.h>
  2. #include <graphics/gfxbase.h>
  3. #include <intuition/intuition.h>
  4. #include <math.h>
  5. #include <libraries/iff.h>
  6. #include <ctype.h>
  7. #include <stdio.h>
  8.  
  9. #define BITS2SHIFT 27
  10.  
  11. double atof();
  12. long atol();
  13. void *OpenLibrary();
  14. int height=256;
  15. struct Window *OpenWindow();
  16. struct Screen *OpenScreen();
  17. struct IntuiMessage *GetMsg();
  18. struct IntuitionBase *IntuitionBase=NULL;
  19. struct GfxBase *GfxBase=NULL;
  20. struct Library *IFFBase=NULL;
  21.  
  22. struct Window *w=NULL;
  23. struct Screen *s=NULL;
  24. struct IntuiMessage *msg;
  25.  
  26. struct NewScreen ns = {0,0,640,512,4,0,0,HIRES|LACE,CUSTOMSCREEN,NULL,NULL,NULL,NULL};
  27.  
  28. struct NewWindow nw = {
  29.     0,1,640,511,-1,-1,VANILLAKEY|CLOSEWINDOW,WINDOWCLOSE|NOCAREREFRESH|
  30.     ACTIVATE,NULL,NULL,NULL,NULL,NULL,0,0,0,0,CUSTOMSCREEN};
  31.  
  32. short ColorMap[32] = {     /* format 0x0RGB */
  33.  /*  0-7  */  0x0000,0x0F00,0x0FB0,0x0FE4,0x0ED9,0x0DDC,0x0CCD,0x0BBC ,
  34.  /*  8-15 */  0x0AAB,0x099A,0x0889,0x0778,0x0667,0x0556,0x0445,0x0334 ,
  35.  /* 16-23 */  0x066F,0x0FFF,0x0EEE,0x0DDD,0x0CCC,0x0BBB,0x0AAA,0x0999 ,
  36.  /* 24-31 */  0x0888,0x0777,0x0666,0x0555,0x0444,0x0333,0x0222,0x0111 };
  37.  
  38. OpenAll()
  39. {
  40.     if (!(IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library", 0L)))
  41.         abort("No Intuition");
  42.     if (!(GfxBase = (struct GfxBase *) OpenLibrary("graphics.library",0L)))
  43.         abort("No GFXBase");
  44.     ns.Height=height=GfxBase->NormalDisplayRows;
  45.     nw.Height=height-1;
  46.  
  47.     if (!(IFFBase = (struct Library *) OpenLibrary(IFFNAME,IFFVERSION)))
  48.         abort("Somebody's using IFF-library - or it is absent");
  49.     if ((s=(struct Screen *)OpenScreen(&ns))==NULL)
  50.         abort("No screen here");
  51.  
  52.     LoadRGB4(&s->ViewPort,&ColorMap[0],(long)1<<s->BitMap.Depth);
  53.     nw.Screen=s;
  54.     if ((w = (struct Window *) OpenWindow(&nw)) == NULL)
  55.         abort("Can't (and won't) open window");
  56. }
  57.  
  58. abort(exitcode)
  59. char *exitcode;
  60. {
  61.     if (exitcode) puts(exitcode);
  62.     if (w) CloseWindow(w);
  63.     if (s) CloseScreen(s);
  64.     if (IFFBase) CloseLibrary(IFFBase);
  65.     if (GfxBase) CloseLibrary(GfxBase);
  66.         OpenWorkBench();
  67.     if (IntuitionBase) CloseLibrary(IntuitionBase);
  68.     exit(0);
  69. }
  70.  
  71. double MSetPot(cx,cy,maxiter)
  72. double cx,cy;
  73. long maxiter;
  74. {
  75.     long iter=0,;
  76.     register double x,y,x2,y2,temp,pot=0.0;
  77.  
  78.     for (x=cx,y=cy,x2=x*x,y2=y*y;(iter<maxiter)&&(x2+y2<10000.0);iter++)
  79.     {
  80.         temp=x2-y2+cx;
  81.         y=2*x*y+cy;
  82.         x=temp;
  83.         x2=x*x;
  84.         y2=y*y;
  85.     }
  86.  
  87.     if (iter<maxiter) pot=0.5*log(x2+y2)/pow(2.0,(double)iter);
  88.     return(pot);
  89. }
  90.  
  91. long oldh[640];
  92.  
  93. MSetCPM3D(xmin,xmax,ymin,ymax,maxiter,angle,scale,lift)
  94. double xmin,xmax,ymin,ymax,scale,lift;
  95. long maxiter,angle;
  96. {
  97.     register long ix,iy,shx,shh,shdep,col,h,maxh,cut,allsteps=0;
  98.     double delta,cx,cy,pot,cutf;
  99.  
  100.     maxh=w->Height;
  101.     if (angle<0)
  102.     {
  103.         allsteps=1;
  104.         angle=-angle;
  105.     }
  106.     cut=w->Height/2;
  107.     if (ymax-ymin!=xmax-xmin) ymax=ymin+xmax-xmin;
  108.     SetAPen(w->RPort,1L);
  109.     for (iy=0;(iy<angle*w->Height/2)&&(msg==NULL);)
  110.     {
  111.         cy=ymin+iy*(ymax-ymin)/s->Width;
  112.         for (ix=0;(ix<s->Width)&&((msg=GetMsg(w->UserPort))==NULL);ix++)
  113.         {
  114.             cx=xmin+ix*(xmax-xmin)/s->Width;
  115.             pot=(double)MSetPot(cx,cy,maxiter);
  116.             h=maxh*(1-pow(pow(2.0,scale)*pot,lift));
  117.             if (iy>0)
  118.             {
  119.                 col=(oldh[ix]+h)/2-oldh[ix-1]+8;
  120.                 if (col<4) col=8;
  121.                 if (col<6) col=7;
  122.                 if ((oldh[ix]>=cut)&&(h>=cut))
  123.                 {
  124.                     col=8;
  125.                     if (oldh[ix]>cut+(maxh-cut)/8) col=7;
  126.                     if (oldh[ix]>cut+(maxh-cut)/6) col=6;
  127.                     if (oldh[ix]>cut+(maxh-cut)/4) col=5;
  128.                     if (oldh[ix]>cut+(maxh-cut)/2) col=4;
  129.                     if (oldh[ix]>cut+3*(maxh-cut)/4) col=3;
  130.                     if (oldh[ix]>cut+5*(maxh-cut)/6) col=2;
  131.                     if (oldh[ix]>cut+7*(maxh-cut)/8) col=1;
  132.                     oldh[ix]=cut;
  133.                 }
  134.                 if (oldh[ix]>=cut) oldh[ix]=cut;
  135.                 if (oldh[ix]<cut)
  136.                 {
  137.                     shh=oldh[ix]-ix;
  138.                     for (shdep=0,shx=ix;(shx<w->Width)&&(shx+shh<cut)&&(shdep<2);shx++)
  139.                         if (shx+shh<oldh[shx]) shdep++;
  140.                     col+=shdep;
  141.                 }
  142.                 if (col>15) col=15;
  143.                 if (pot==0.0) col=0;
  144.                 if (ix>0)
  145.                 {
  146.                     Move(w->RPort,ix,(long)(w->Height/2+(iy-1)/angle));
  147.                     SetAPen(w->RPort,col);
  148.                     Draw(w->RPort,ix,(long)(w->Height/2+(iy-1)/angle-oldh[ix]));
  149.                 }
  150.             }
  151.             oldh[ix]=h;
  152.         }
  153.         if (allsteps==0) iy+=angle;
  154.         else iy++;
  155.     }
  156.     if (msg==NULL)
  157.     {
  158.         for (ix=1;ix<s->Width;ix++)
  159.         {
  160.             SetAPen(w->RPort,9L);
  161.             if (oldh[ix]>cut) oldh[ix]=cut;
  162.             Move(w->RPort,ix,(long)(w->Height/2+(iy-1)/angle));
  163.             Draw(w->RPort,ix,(long)(w->Height/2+(iy-1)/angle-oldh[ix]+1));
  164.         }
  165.     }
  166. }
  167.  
  168. getdoub(doub,datafile)
  169. double *doub;
  170. FILE *datafile;
  171. {
  172.     int i;
  173.     char doublebuf[30];
  174.  
  175.     i=-1;
  176.     doublebuf[0]=0;
  177.     do fread(&doublebuf[++i],1,1,datafile);
  178.     while ((doublebuf[i]!=';')&&(i<30));
  179.     doublebuf[i]=0;
  180.     *doub=atof(&doublebuf[0]);
  181. }
  182.  
  183. getlong(lon,datafile)
  184. long *lon;
  185. FILE *datafile;
  186. {
  187.     int i;
  188.     char doublebuf[30];
  189.  
  190.     i=-1;
  191.     doublebuf[0]=0;
  192.     do fread(&doublebuf[++i],1,1,datafile);
  193.     while ((doublebuf[i]!=';')&&(i<30));
  194.     *lon=atol(&doublebuf[0]);
  195. }
  196.  
  197. DisplayUsage(fromcli)
  198. int fromcli;
  199. {
  200.     puts("CPM - 3D Mandelbrot program using Continuous Potiential Method");
  201.     puts("      1989 by Lars R. Clausen (2:230/22.34)");
  202.     puts("      Algorithm from 'The Science of Fractal Images'.");
  203.     puts("Usage: CPM [datafile] or");
  204.     puts("       CPM xmin xmax ymin ymin maxit angle scale lift H|L outputfile");
  205.     puts("This program is PD, copy it as you see fit. (No fun for hackers!)");
  206.     if (fromcli==0) gets();
  207.     exit(0);
  208. }
  209.  
  210. DoSize(size)
  211. char size;
  212. {
  213.     switch (size)
  214.     {
  215.         case 'H':   ns.Height=2*height; nw.Height=2*height-1;
  216.                     ns.Width=nw.Width=640;
  217.                     ns.ViewModes=HIRES|LACE;
  218.                     break;
  219.         case 'L':   ns.Height=height; nw.Height=height-1;
  220.                     ns.Width=nw.Width=320;
  221.                     ns.ViewModes=0;
  222.                     break;
  223.         default:     puts("Illegal screen type");
  224.     }
  225. }
  226.  
  227. main(argc,argv)
  228. int argc;
  229. char *argv[];
  230. {
  231.     long i,end=0,fromfile=1,maxit,angle;
  232.     FILE *datafile=NULL;
  233.     double xmin,xmax,ymin,ymax,scale,lift;
  234.     char size,oldsize,savefile[200],*dataname="CPMDataFile";
  235.  
  236.     if (argc==0) DisplayUsage(0);
  237.     if ((argc==2)&&(strcmp(argv[1],"?")==0)) DisplayUsage(1);
  238.     switch (argc)
  239.     {
  240.         case 2: dataname=argv[1]; break;
  241.         case 11:
  242.             xmin=atof(argv[1]);
  243.             xmax=atof(argv[2]);
  244.             ymin=atof(argv[3]);
  245.             ymax=atof(argv[4]);
  246.             maxit=atoi(argv[5]);
  247.             angle=atoi(argv[6]);
  248.             scale=atof(argv[7]);
  249.             lift=atof(argv[8]);
  250.             size=*argv[9];
  251.             strcpy(savefile,argv[10]);
  252.             fromfile=0;
  253.             size=toupper(size);
  254.             if (size!='H') DoSize(size);
  255.         case 1: break;
  256.         default: DisplayUsage(argc);
  257.     }
  258.     OpenAll();
  259.  
  260. /* format xmin;xmax;ymin;ymax;maxit;angle;scale;buttom;size;savefile[EOL] */
  261.     if (fromfile)
  262.     {
  263.         datafile=fopen(dataname,"r");
  264.         if (datafile==NULL) abort("Can't open file");
  265.     }
  266.     do
  267.     {
  268.         if (fromfile)
  269.         {
  270.             getdoub(&xmin,datafile);
  271.             getdoub(&xmax,datafile);
  272.             getdoub(&ymin,datafile);
  273.             getdoub(&ymax,datafile);
  274.             getlong(&maxit,datafile);
  275.             getlong(&angle,datafile);
  276.             getdoub(&scale,datafile);
  277.             getdoub(&lift,datafile);
  278.             do
  279.                 fread(&size,1,1,datafile);
  280.             while (!(isalpha(size)));
  281.             size=toupper(size);
  282.             if (oldsize!=size)
  283.             {
  284.                 CloseWindow(w);
  285.                 CloseScreen(s);
  286.                 DoSize(size);
  287.                 if ((s=(struct Screen *)OpenScreen(&ns))==NULL)
  288.                     abort("No screen here");
  289.  
  290.                 LoadRGB4(&s->ViewPort,&ColorMap[0],(long)1<<s->BitMap.Depth);
  291.                 nw.Screen=s;
  292.                 if ((w = (struct Window *) OpenWindow(&nw)) == NULL)
  293.                     abort("Can't (and won't) open window");
  294.             }
  295.             i=-1;
  296.             fread(&savefile[0],1,1,datafile);
  297.             do
  298.                 fread(&savefile[++i],1,1,datafile);
  299.             while ((savefile[i]!=EOF)&&(savefile[i]!='\n')&&(i<200));
  300.             if (savefile[i]==EOF) end=1;
  301.             savefile[i]=0;
  302.             if (i==200) {fclose(datafile);abort("filename too long");}
  303.         }
  304.         Move(w->RPort,0L,0L);
  305.         ClearScreen(w->RPort);
  306.         printf("Doing: %s Maxit %ld Angle %ld Scale %2.0f Lift %1.5f Size %c\n",savefile,maxit,angle,scale,lift,size);
  307.         MSetCPM3D(xmin,xmax,ymin,ymax,maxit,angle,scale,lift);
  308.         if (msg==NULL) SaveBitMap(savefile,&s->BitMap,&s->ViewPort.ColorMap->ColorTable[0],1L);
  309.         Move(w->RPort,0L,0L);
  310.         ClearScreen(w->RPort);
  311.         if (msg->Class==CLOSEWINDOW) end=1;
  312.         for (msg=GetMsg(w->UserPort);msg!=NULL;ReplyMsg(msg),msg=GetMsg(w->UserPort));
  313.         msg=NULL;
  314.     }
  315.     while ((end==0)&&(fromfile==1));
  316.     if (fromfile) fclose(datafile);
  317.     abort(NULL);
  318. }
  319.